package com.suray.rgv.son.mother.lock;

import com.suray.basic.wcs.utils.LoggerType;
import com.suray.rgv.son.mother.util.RgvSMLogger;

import java.util.HashSet;
import java.util.Set;

/**
 * 子母车任务锁管理
 * 防止子母车同时执行任务
 */
public class LockManage {
    Set<LockContainer> lockContainers;

    public LockManage() {
        lockContainers = new HashSet<>();
    }

    /**
     * 加锁
     * @param key
     * @param value
     * @return
     */
    public synchronized boolean getLock(Object key, Object value) {
        for (LockContainer lockContainer : lockContainers) {
            if (lockContainer.lockObj.equals(value)) {
                if (lockContainer.lockKey.equals(key)) {
                    return true;
                } else {
                    RgvSMLogger.warn(LoggerType.LOCK, key, value, "被" + lockContainer.lockKey + "锁定小车",
                            this.getClass());
                    return false;
                }
            }
        }

        RgvSMLogger.warn(LoggerType.LOCK, key, value, "锁定小车成功", this.getClass());
        lockContainers.add(new LockContainer(key, value));
        return true;
    }

    /**
     * 释放锁
     * @param key
     * @return
     */
    public synchronized boolean releaseLock(Object key) {
        try {
            for (LockContainer lockContainer : lockContainers) {
                if (lockContainer.lockKey.equals(key)) {
                    RgvSMLogger.warn(LoggerType.LOCK, key, lockContainer.lockObj, "解锁小车成功", this.getClass());
                    lockContainers.remove(lockContainer);
                    break;
                }
            }
        } catch (Exception e) {
            RgvSMLogger.error(LoggerType.ERROR, key, e.getMessage(), "解锁小车失败", this.getClass());
        }

        return true;
    }

    /**
     * 是否被上锁
     * @param value
     * @return
     */
    public synchronized boolean isLock(Object value) {
        for (LockContainer lockContainer : lockContainers) {
            if (lockContainer.getLockObj().equals(value)) {
                return true;
            }
        }

        return false;
    }
}
